/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2023. All rights reserved.
 * Description: ai stats log timer out proc class
 */

#include "infra/om/stats/ai_stats_log_timer_out_proc.h"

#include <string>

#include "infra/base/assertion.h"
#include "infra/base/api_export.h"
#include "infra/om/stats/ai_stats_log_utils.h"
#ifdef __OHOS__
#include "ha_client_lite_api.h"
#endif
namespace hiai {
AiStatsLogTimerOutProc* AiStatsLogTimerOutProc::instance_ = nullptr;
std::mutex AiStatsLogTimerOutProc::instanceLock_;
INFRA_API_EXPORT AiStatsLogTimerOutProc* AiStatsLogTimerOutProc::GetInstance()
{
    std::lock_guard<std::mutex> lck(instanceLock_);
    if (instance_ == nullptr) {
        instance_ = new (std::nothrow) AiStatsLogTimerOutProc();
        HIAI_EXPECT_NOT_NULL_R(instance_, nullptr);
    }
    return instance_;
}
/*lint -e1744*/
AiStatsLogTimerOutProc::AiStatsLogTimerOutProc()
{
    // 每新增一个打点engine，都需要添加到这里，供定时器统一管理所有的engine
    statsLogWriters_.push_back(AiMMStatsLogWriter::GetInstance());
    statsLogWriters_.push_back(AiHiAiEngineStatsLogWriter::GetInstance());
    statsLogWriters_.push_back(AiANNStatsLogWriter::GetInstance());
    statsLogWriters_.push_back(AiHiAiHCSStatsLogWriter::GetInstance());
    statsLogWriters_.push_back(AiHiAiDDKStatsLogWriter::GetInstance());
}
/*
 * 统计日志定时器超时处理
 * 1.所有engine进行日志统计时共用一个定时器，定时器时长为 STATS_LOG_TIMER，目前设置为20分钟
 * 2.定时器超时后，如果存在超出保存时长的日志，则删除；如果存在缓存日志，则将缓存日志写入文件
 * 3.server启动时，需要启动该定时器
 */
void AiStatsLogTimerOutProc::Timeout()
{
    STATS_LOGD("AiStatsLogTimerOutProc Timeout");
    for (int i = 0; i < static_cast<int>(statsLogWriters_.size()); ++i) {
        if (statsLogWriters_[i] == nullptr) {
            STATS_LOGW("statsLogWriters_[%d] is nullptr.", i);
            continue;
        }
        statsLogWriters_[i]->WriteToFile();
        statsLogWriters_[i]->DeleteLogFile();
    }
#ifdef __OHOS__
    std::vector<OHOS::HaCloud::HaEventLite> events;
    std::map<AiStatsEngineType, std::string> engineType{ {AI_STATS_HIAI_MNGR, "AI_STATS_HIAI_MNGR"}};
    std::vector<char*> logBuffer;
    for (auto type : engineType) {
        uint32_t logSize = AiStatsLogCfgUtils::GetEngineStatsLogSize(type.first);
        HIAI_EXPECT_TRUE_VOID(logSize != 0);
        char* statsLog = reinterpret_cast<char*>(malloc(sizeof(char) * logSize));
        AiStatsLogCfgUtils::GetEngineStatsLog(statsLog, logSize, type.first);
        std::string logStr(statsLog, logSize);
        AiStatsLogCfgUtils::DeleteEngineStatsLog(type.first);
        OHOS::HaCloud::HaEventLite event;
        event.instanceTag = "hiaiserver";
        event.eventId = type.second;
        event.eventType = OHOS::HaCloud::EventTypeLite::maintenance;
        event.properties.emplace(type.second, logStr);
        events.emplace_back(event);
        logBuffer.push_back(statsLog);
    }

    if (events.size() != 0) {
        // 调用打点接口（instanceTag需与SetConfigOptions中instanceTag一致，events 中所有instanceTag一致）
        OHOS::HaCloud::HaResponseLite rsp = OHOS::HaCloud::HaClientLiteApi::OnEvents("hiaiserver", events);
        if (rsp.code != 0) {
            STATS_LOGE("AiStatsLogTimerOutProc OnEvents %s", rsp.message.c_str());
        }
        for (auto buffer : logBuffer) {
            free(buffer);
        }
    }
#endif
}
} // end namespace ai
